import type { FC } from 'react';
import React, { useEffect } from 'react';
import { makeStyles, createStyles, ThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import moment from 'moment';
import SketchPicker from '@/components/SketchPickerCu';
import {
  TextField,
  Switch,
  ListItem,
  List,
  FormHelperText,
  ListSubheader,
  FormControl,
  FormControlLabel,
  FormLabel,
  MenuItem,
  Radio,
  RadioGroup,
  Slider,
  useMediaQuery,
  Button,
  Grid,
} from '@material-ui/core';
import { useLocation } from 'umi';
import { PageLoading } from '@ant-design/pro-layout';
import DateFnsUtils from '@date-io/moment'; // choose your lib
import { DatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
import btnStyles from './index.module.less';
import SketchPickerCus from '@/components/SketchPickerCus';

moment.locale('zh-cn');

let scConfig: settingGroup[] = [];

type settingGroup = {
  title: string;
  html?: string;
  settings: settingType[];
};

type settingType = {
  id: string;
  name: string;
  val: any;
  type:
    | 'boolean'
    | 'input'
    | 'select'
    | 'radio'
    | 'colorPicker'
    | 'colorPickers'
    | 'slider'
    | 'datePicker';
  desc?: string;
  placeholder?: string;
  options?: { value: any; text: string }[];
  min?: number;
  max?: number;
  step?: number;
  format?: string;
};

const FormItem: FC<{ label: string; desc?: string }> = (props) => {
  return (
    <>
      <Grid container alignItems={'center'}>
        <Grid item xs={6}>
          <FormLabel component="div">{props.label}</FormLabel>
        </Grid>
        <Grid
          item
          xs={6}
          style={{
            display: 'flex',
            justifyContent: 'flex-end',
            alignItems: 'center',
          }}
        >
          {props.children}
        </Grid>
      </Grid>
      <FormHelperText>{props.desc}</FormHelperText>
    </>
  );
};

const FormItemSwitch: FC<{ setting: settingType; value: boolean; onChange: any }> = ({
  setting,
  value,
  onChange,
}) => {
  return (
    <FormItem desc={setting.desc} label={setting.name}>
      <Switch name={setting.id} checked={value} onChange={onChange} />
    </FormItem>
  );
};

export default () => {
  const { query }: any = useLocation();
  const [state, setState] = React.useState<any>({});
  useEffect(() => {
    const settingConfig = query.config;
    try {
      scConfig = JSON.parse(settingConfig) as settingGroup[];
    } catch (e) {
      console.log(e);
    }
    const initialValue: any = {};
    scConfig.forEach((item) => {
      item.settings.forEach((setting) => {
        initialValue[setting.id] = setting.val;
      });
    });
    setState(initialValue);
  }, [query]);
  const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
  const theme = React.useMemo(
    () =>
      createMuiTheme({
        palette: {
          type: prefersDarkMode ? 'dark' : 'light',
        },
      }),
    [prefersDarkMode],
  );
  const useStyle = makeStyles(() => {
    return createStyles({
      root: {
        width: '100%',
        backgroundColor: prefersDarkMode ? theme.palette.common.black : theme.palette.common.white,
      },
    });
  });

  const classes = useStyle();

  const handleCheckedChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setState({ ...state, [event.target.name]: event.target.checked });
  };

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setState({ ...state, [event.target.name]: event.target.value });
  };

  const handleCommonChange = (name: string, value: any) => {
    setState({ ...state, [name]: value });
  };

  const handleClick = (key: string) => {
    if (key === 'rest') {
      const initValue: Record<string, null> = {};
      Object.keys(state).forEach((index: string) => {
        initValue[index] = null;
      });
      console.log(initValue);
      setState(initValue);
    }
    window.dispatchEvent(
      new CustomEvent('catalog-event', {
        detail: { ...state, key },
      }),
    );
  };

  const getFormItem = (config: settingType) => {
    const configValue = state[config.id];
    const props: any = {
      name: config.id,
      id: config.id,
      onChange: handleChange,
    };
    switch (config.type) {
      case 'boolean':
        return (
          <FormItemSwitch setting={config} onChange={handleCheckedChange} value={configValue} />
        );
      case 'input':
        return (
          <TextField
            fullWidth
            color="secondary"
            label={config.name}
            helperText={config.desc}
            placeholder={config.placeholder}
            {...props}
            value={configValue || ''}
          />
        );
      case 'select':
        return (
          <TextField
            select
            fullWidth
            {...props}
            color="secondary"
            label={config.name}
            helperText={config.desc}
            placeholder={config.placeholder}
            value={configValue || undefined}
          >
            {config.options?.map((item, index) => {
              return (
                <MenuItem key={`select-${index}`} value={item.value}>
                  {item.text}
                </MenuItem>
              );
            })}
          </TextField>
        );
      case 'radio':
        return (
          <FormControl component="fieldset" fullWidth>
            <FormLabel component="legend">{config.name}</FormLabel>
            <RadioGroup aria-label={config.name} {...props} value={config || undefined}>
              {config.options?.map((item, index) => {
                return (
                  <FormControlLabel
                    key={`radio-${index}`}
                    control={<Radio value={item.value} />}
                    label={item.text}
                  />
                );
              })}
            </RadioGroup>
            <FormHelperText>{config.desc}</FormHelperText>
          </FormControl>
        );
      case 'colorPicker':
        return (
          <FormItem desc={config.desc} label={config.name}>
            <SketchPicker
              colors={configValue || '#fff'}
              onChangeComplete={(color) => {
                handleCommonChange(config.id, color.hex);
              }}
            />
          </FormItem>
        );
      case 'colorPickers':
        return (
          <FormItem desc={config.desc} label={config.name}>
            <SketchPickerCus
              colors={configValue}
              onChange={(colors) => {
                handleCommonChange(config.id, colors);
                return null;
              }}
            />
          </FormItem>
        );
      case 'slider':
        return (
          <FormControl component="fieldset" fullWidth>
            <FormLabel component="legend">{config.name}</FormLabel>
            <FormControlLabel
              control={
                <Slider
                  name={config.id}
                  style={{ width: '100%', margin: '0 20px' }}
                  defaultValue={parseFloat(config.val)}
                  step={config.step || 0.1}
                  max={config.max || 1}
                  min={config.min || 0}
                  onChange={(_, value) => handleCommonChange(config.id, value)}
                  valueLabelDisplay="auto"
                  aria-labelledby="discrete-slider-small-steps"
                />
              }
              label={<span className={'MuiFormLabel-root'}>{configValue}</span>}
            />
            <FormHelperText>{config.desc}</FormHelperText>
          </FormControl>
        );
      case 'datePicker':
        return (
          <FormItem desc={config.desc} label={config.name}>
            <MuiPickersUtilsProvider utils={DateFnsUtils}>
              <DatePicker
                format={config.format || 'YYYY-MM-DD'}
                value={!configValue ? null : moment(configValue).toDate()}
                onChange={(value) => {
                  const momentValue = value as moment.Moment;
                  handleCommonChange(config.id, momentValue.format(config.format || 'YYYY-MM-DD'));
                }}
              />
            </MuiPickersUtilsProvider>
          </FormItem>
        );
      default:
        return null;
    }
  };
  return (
    <ThemeProvider theme={theme}>
      {Object.keys(state).length ? (
        scConfig.map((item, index) => {
          return (
            <List
              key={`title_${index}`}
              subheader={<ListSubheader>{item.title}</ListSubheader>}
              className={classes.root}
            >
              {item.html && (
                <ListItem key={'setting-html'}>
                  <div
                    className={'MuiFormLabel-root'}
                    dangerouslySetInnerHTML={{ __html: item.html }}
                  />
                </ListItem>
              )}
              {item.settings.map((setting, sIndex: number) => {
                const config = setting as settingType;
                return (
                  <ListItem key={`setting-${sIndex}`} style={{ padding: '20px' }}>
                    {getFormItem(config)}
                  </ListItem>
                );
              })}
            </List>
          );
        })
      ) : (
        <PageLoading />
      )}
      <div className={`${btnStyles.fixed} ${classes.root}`}>
        <Button onClick={() => handleClick('rest')} variant="contained">
          重置
        </Button>
        <Button
          onClick={() => handleClick('setting')}
          variant="contained"
          color="secondary"
          style={{ marginLeft: 'auto' }}
        >
          保存
        </Button>
      </div>
    </ThemeProvider>
  );
};
